/**
 * \file            comm.c
 * \brief           通信协议处理实现
 */
#include "comm.h"
#include <string.h>

/*--------------------- 静态函数声明 ---------------------*/
static uint8_t bit8_xor_check_sum(const uint8_t* buf, uint32_t len);
static void hex_to_string(uint8_t* p_hex, uint8_t* p_ascii, uint32_t len);
static void string_to_hex(uint8_t* src, uint32_t src_len, uint8_t* p_ascii, uint32_t len);
static char* my_mem_str(const char* str1, uint32_t len1, const char* str2);

/*--------------------- 函数实现 ---------------------*/
/**
 * \brief           8位异或校验计算
 * \param[in]       buf: 待校验数据缓冲区
 * \param[in]       len: 数据长度
 * \return          校验结果
 */
static uint8_t bit8_xor_check_sum(const uint8_t* buf, uint32_t len) {
    uint8_t checksum = 0;
    for (uint32_t i = 0; i < len; ++i) {
        checksum ^= buf[i];
    }
    return checksum;
}

/**
 * \brief           十六进制数据转ASCII字符串
 * \param[in]       p_hex: 十六进制数据指针
 * \param[out]      p_ascii: 输出ASCII缓冲区
 * \param[in]       len: 转换长度
 */
static void hex_to_string(uint8_t* p_hex, uint8_t* p_ascii, uint32_t len) {
    unsigned char nibble[2];
    for (uint32_t i = 0; i < len; i++) {
        nibble[0] = (p_hex[i] & 0xF0) >> 4;
        nibble[1] = p_hex[i] & 0x0F;
        for (uint32_t j = 0; j < 2; j++) {
            p_ascii[j + i*2] = (nibble[j] < 10) ? 
                (nibble[j] + 0x30) : 
                (nibble[j] - 10 + 'A');
        }
    }
    p_ascii[len*2] = 0x0A;  /* 添加换行 */
    p_ascii[len*2 + 1] = 0x0D;  /* 添加回车 */
}

/**
 * \brief           ASCII字符串转十六进制数据
 * \param[in]       src: 源字符串
 * \param[in]       src_len: 源字符串长度
 * \param[out]      p_ascii: 输出缓冲区
 * \param[in]       len: 转换长度
 */
static void string_to_hex(uint8_t* src, uint32_t src_len, uint8_t* p_ascii, uint32_t len) {
    if ((src_len % 2 != 0) || (src_len / 2 != len) || src == NULL || p_ascii == NULL) {
        return;
    }

    for (uint32_t i = 0; i < src_len; i += 2) {
        uint8_t high = (src[i] > '9') ? src[i] - 55 : src[i] - 48;
        uint8_t low = (src[i+1] > '9') ? src[i+1] - 55 : src[i+1] - 48;
        p_ascii[i/2] = (high << 4) | low;
    }
}

/**
 * \brief           内存块查找子串
 * \param[in]       buf: 目标缓冲区
 * \param[in]       buf_size: 缓冲区大小
 * \param[in]       sub_info: 子串指针
 * \param[in]       info_size: 子串长度
 * \return          首次匹配位置指针，未找到返回NULL
 */
char* mem_find(const char* buf, int buf_size, const char* sub_info, int info_size) {
    if (buf == NULL || buf_size <= 0 || sub_info == NULL || info_size <= 0) {
        return NULL;
    }

    for (int i = 0; i <= buf_size - info_size; ++i) {
        if (memcmp(&buf[i], sub_info, info_size) == 0) {
            return (char*)&buf[i];
        }
    }
    return NULL;
}

/**
 * \brief           内存字符串查找
 * \param[in]       str1: 目标字符串
 * \param[in]       len1: 目标字符串长度
 * \param[in]       str2: 待查找字符串
 * \return          首次匹配位置指针，未找到返回NULL
 */
static char* my_mem_str(const char* str1, uint32_t len1, const char* str2) {
    uint32_t len2 = strlen(str2);
    if (len2 == 0 || len1 < len2) {
        return NULL;
    }

    for (uint32_t i = 0; i <= len1 - len2; ++i) {
        if (memcmp(&str1[i], str2, len2) == 0) {
            return (char*)&str1[i];
        }
    }
    return NULL;
}

/**
 * \brief           8位CRC校验
 * \param[in]       info: 待校验数据
 * \param[in]       len: 数据长度
 * \return          校验结果：1-成功，0-失败
 */
uint8_t bit8_crc_check(uint8_t* info, uint16_t len) {
    char* scrc_pos = strstr((char*)info, "*");
    if (scrc_pos == NULL) {
        return 0;
    }

    uint8_t crc = comm_handle.bit8_xor_check_sum(info + 1, scrc_pos - (char*)info - 1);
    uint8_t recv_crc;
    comm_handle.string_to_hex((uint8_t*)scrc_pos + 1, 2, &recv_crc, 1);
    
    return (crc == recv_crc) ? 1 : 0;
}

/* 全局通信处理实例初始化 */
comm_handle_t comm_handle = {
    .bit8_xor_check_sum = bit8_xor_check_sum,
    .hex_to_string = hex_to_string,
    .string_to_hex = string_to_hex,
    .mem_find = mem_find,
    .bit8_crc_check = bit8_crc_check,
    .my_mem_str = my_mem_str,
};

/* 文件末尾保留空行 */